/*  generalthread.hpp
    Created by Garrett Williams GoatbitsSoftware
    version: 020808
    Licence: GPL

    The GeneralThread class is composed of three parts.  The mutex, the condition and the main
    GeneralThread class.  The mutex is seperate from the main class so the mutex can be shared 
    between threads.  The GeneralCondition class provides functionality for stoping and sleeping
    the thread.  It was made the parent of the GeneralThread for simplicity of code not as a 
    design concept.  See the example in threadtest.cpp for an example of its usage.
 */


#include <pthread.h>

#ifndef GENERAL_THREAD_H
#define GENERAL_THREAD_H

namespace GeneralThread_NS
{

class GeneralMutex
{
    public:
        GeneralMutex();
       ~GeneralMutex();

        void lock();
        void unlock();
    private:
        void destroy();

        pthread_mutex_t _mutex;
};

class GeneralCondition
{
    public:
        GeneralCondition();
       ~GeneralCondition();

    private:
        void destroy();

        pthread_mutex_t    _mutex;
        pthread_cond_t     _condition;
    protected:
        int timeWait(unsigned); // wait time in microseconds.
        void condWait();
        void condGo();
};

class GeneralThread :public GeneralCondition
{
    public:
        GeneralThread(GeneralMutex&);
        virtual ~GeneralThread();
        
        int create(void*);
        // Handle the thread methods.
        void lock();
        void unlock();
        int  threadID(){return (int)_thread;} // this is incorrect.

        bool  running();
        void  running(bool);
        bool  stopCond();
        void  stopCond(bool);
        bool  lockMutex();
        void  lockMutex(bool);
        unsigned  waitCond();
        void      waitCond(unsigned);
    protected:
        static void* threadCall(void*);   // registered function. called by thread.
        virtual void process(void*){}     // user defined process.
        virtual void timeInterupted(){}   // used for interupting timewait.
        virtual void timeCompleted(){}    // used for time ran out in timewait.
        void stop();
        // accessors
        void* caller() ;
        void  caller(void* a);

    private:
        pthread_t         _thread;
        int               _thread_id;
        void             *_caller;
        GeneralMutex     &_mutex;
        //GeneralCondition &_condition;
        bool              _running;
        bool              _stop_cond;
        bool              _lock_mutex;
        unsigned          _wait_cond;
};
}
#endif

